/**
 * representation of Konsument
 * @author Lukas Koell
 * @author Johannes Riedmann
 * @author David Medenjak
 */

public class Konsument extends Erzeuger {

    /** storage the worker gets hit material from */
    protected final Lager inputStorage;
    /** amount of units the worker gets from inputStorage in 1 cycle */
    protected int inAmount;
    /** number of units the worker is consuming */
    private int consumeCount;
    /** number of units the worker has taken */
    private int taken;

    public Konsument(String name,
            Lager outputStorage, int produceCount, Lager inputStorage, int consumeCount) {
        super(name, outputStorage, produceCount);
        this.inputStorage = inputStorage;
        this.consumeCount = consumeCount;
        this.taken = 0;
    }

    @Override
    public void run() {
        while (run) {
            if (this.isInterrupted()) {
                terminate();
                if (this.getClass().getSimpleName() == "WildschweinJaeger") {
                    System.out.println("Wildschweinjaeger is interrupted!");
                }
                run = false;
                return;
            }

            getRessources();
            if (!run) {
                return;
            }

            // work
            try {
                Thread.sleep(workDuration);
            } catch (InterruptedException e) {
                terminate();
                if (this.getClass().getSimpleName() == "WildschweinJaeger") {
                    System.out.println("Wildschweinjaeger is interrupted!");
                }
                run = false;
//                System.out.println(name + " got fired and won't finish his work he started. "
//                        + taken + " items are lost.");
                return;
            }
            taken = 0;

            depositRessources();
        }
    }

    /**
     * worker is taking units out of inputStorage
     * is inputStorage is empty, the worker has to wait
     */
    private void getRessources() {
        synchronized (inputStorage) {
            while (taken < consumeCount) {
                while (!inputStorage.canTakeOut()) {
                    try {
                        inputStorage.wait();
//                        System.out.println("## " + name + " woke up.");
                    } catch (InterruptedException ex) {
                        terminate();
                        if (this.getClass().getSimpleName() == "WildschweinJaeger") {
                            System.out.println("Wildschweinjaeger is interrupted!");
                        }
                        run = false;
                        return;
                    }
                }
                inputStorage.setConsumer(this, this);
                taken += inputStorage.takeOut(consumeCount - taken, this);
                if (taken == 0) {
                    try {
                        inputStorage.wait();
                    } catch (InterruptedException ex) {
                        terminate();
                        if (this.getClass().getSimpleName() == "WildschweinJaeger") {
                            System.out.println("Wildschweinjaeger is interrupted!");
                        }
                        run = false;
                        return;
                    }
                    continue;
                }
//                System.out.println(name + " now has taken " + taken + "/" + consumeCount);
            }
            inputStorage.setConsumer(this, null);
        }
    }
}
